package com.zp.drug.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zp.base.api.RemotePriceListService;
import com.zp.base.api.bo.PriceListBo;
import com.zp.common.core.constant.BaseConstants;
import com.zp.common.core.constant.PriceConstants;
import com.zp.common.core.utils.DateUtils;
import com.zp.common.core.utils.StringUtils;
import com.zp.common.myBatis.core.page.PageQuery;
import com.zp.common.myBatis.core.page.TableDataInfo;
import com.zp.common.satoken.utils.LoginHelper;
import com.zp.drug.api.bo.DrugInfoBo;
import com.zp.drug.api.bo.DrugPriceBo;
import com.zp.drug.api.vo.DrugPriceVo;
import com.zp.drug.entity.DrugPrice;
import com.zp.drug.entity.DrugStock;
import com.zp.drug.mapper.DrugPriceMapper;
import com.zp.drug.mapper.DrugStockMapper;
import com.zp.drug.service.IDrugPriceLogService;
import com.zp.drug.service.IDrugPriceService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 药品价表Service业务层处理
 *
 * @author zhang peng
 * @ date 2023-06-05
 */
@RequiredArgsConstructor
@Service
public class DrugPriceServiceImpl implements IDrugPriceService {

    private final DrugPriceMapper baseMapper;
    @DubboReference
    private RemotePriceListService priceListService;
    private final DrugStockMapper drugStockMapper;
    private final IDrugPriceLogService drugPriceLogService;

    /**
     * 查询药品价表
     */
    @Override
    public DrugPriceVo queryById (String id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询药品价表列表(分页)
     */
    @Override
    public TableDataInfo<DrugPriceVo> queryPageList (DrugPriceBo bo, PageQuery pageQuery) {
//        LambdaQueryWrapper<DrugPrice> lqw = buildQueryWrapper(bo);
//        Page<DrugPriceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        Page<DrugPriceVo> result = baseMapper.selectVoPage(pageQuery.build(), bo);
        return TableDataInfo.build(result);
    }

    /**
     * 查询药品价表列表(不分页)
     */
    @Override
    public List<DrugPriceVo> queryList (DrugPriceBo bo) {
        LambdaQueryWrapper<DrugPrice> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<DrugPrice> buildQueryWrapper (DrugPriceBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<DrugPrice> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getDrugCode()), DrugPrice::getDrugCode, bo.getDrugCode());
        lqw.eq(StringUtils.isNotBlank(bo.getDrugInfoId()), DrugPrice::getDrugInfoId, bo.getDrugInfoId());
        lqw.eq(StringUtils.isNotBlank(bo.getMedicalInsuranceType()), DrugPrice::getMedicalInsuranceType, bo.getMedicalInsuranceType());
        lqw.eq(StringUtils.isNotBlank(bo.getPriceId()), DrugPrice::getPriceId, bo.getPriceId());
        lqw.eq(StringUtils.isNotBlank(bo.getPackageSpec()), DrugPrice::getPackageSpec, bo.getPackageSpec());
        lqw.eq(StringUtils.isNotBlank(bo.getPackageUnits()), DrugPrice::getPackageUnits, bo.getPackageUnits());
        lqw.eq(bo.getNetworkPrice() != null, DrugPrice::getNetworkPrice, bo.getNetworkPrice());
        lqw.eq(bo.getTradePrice() != null, DrugPrice::getTradePrice, bo.getTradePrice());
        lqw.eq(bo.getRetailPrice() != null, DrugPrice::getRetailPrice, bo.getRetailPrice());
        lqw.eq(bo.getStartDate() != null, DrugPrice::getStartDate, bo.getStartDate());
        lqw.eq(bo.getStopDate() != null, DrugPrice::getStopDate, bo.getStopDate());
        lqw.eq(StringUtils.isNotBlank(bo.getClassOnRcpt()), DrugPrice::getClassOnRcpt, bo.getClassOnRcpt());
        lqw.eq(StringUtils.isNotBlank(bo.getClassOnInp()), DrugPrice::getClassOnInp, bo.getClassOnInp());
        lqw.eq(StringUtils.isNotBlank(bo.getClassOnReckoning()), DrugPrice::getClassOnReckoning, bo.getClassOnReckoning());
        lqw.eq(StringUtils.isNotBlank(bo.getSubjCode()), DrugPrice::getSubjCode, bo.getSubjCode());
        lqw.eq(StringUtils.isNotBlank(bo.getClassOnMr()), DrugPrice::getClassOnMr, bo.getClassOnMr());
        lqw.eq(bo.getPriceMax() != null, DrugPrice::getPriceMax, bo.getPriceMax());
        lqw.eq(StringUtils.isNotBlank(bo.getSupplySign()), DrugPrice::getSupplySign, bo.getSupplySign());
        lqw.eq(StringUtils.isNotBlank(bo.getPackSize()), DrugPrice::getPackSize, bo.getPackSize());
        lqw.eq(StringUtils.isNotBlank(bo.getOrgId()), DrugPrice::getOrgId, bo.getOrgId());
        lqw.eq(StringUtils.isNotBlank(bo.getRemarks()), DrugPrice::getRemarks, bo.getRemarks());
        lqw.eq(bo.getRatio() != null, DrugPrice::getRatio, bo.getRatio());
        lqw.orderByDesc(DrugPrice::getPackSize);
        return lqw;
    }

    /**
     * 新增药品价表
     */
    @Override
    @Transactional
    public Boolean insertByBo (DrugPriceBo bo) {
        DrugPrice add = BeanUtil.toBean(bo, DrugPrice.class);
        validEntityBeforeSave(add);
        add.initEntity();
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        savePriceList(bo);
        return flag;
    }

    @Transactional
    public void savePriceList (DrugPriceBo bo) {
        PriceListBo priceBo = new PriceListBo();
        String priceId = "";
        this.initPriceList(priceBo, bo);
        priceBo.setIntoItemCheck(true);
        // 调用 价表保存
        PriceListBo newBo = priceListService.insertByBo(priceBo);
        if (ObjectUtil.isNotNull(priceId)) {
            priceId = newBo.getPriceId();
        }
        DrugPrice drugPrice = new DrugPrice();
        drugPrice.setId(bo.getId());
        drugPrice.setPriceId(priceId);
        // 保存drug_price_log 药品价表日志
        bo.setPriceId(priceId);
        bo.setOperationType(PriceConstants.OPERATION_TYPE_INSERT);
        drugPriceLogService.initDrugPriceListLog(bo);
        baseMapper.updateById(drugPrice);
    }

    public void initPriceList (PriceListBo priceBo, DrugPriceBo bo) {
        BeanUtil.copyProperties(bo, priceBo);
        priceBo.setPriceId(bo.getId());
        // 设置项目分类
        priceBo.setItemClass(StringUtils.equals(bo.getDrugClass(), BaseConstants.DRUG_CLASS_WESTERN) ?
                BaseConstants.ITEM_CLASS.WESTERN : BaseConstants.ITEM_CLASS.CHINESE);
        priceBo.setItemCode(bo.getDrugCode());
        priceBo.setItemName(bo.getDrugName());
        priceBo.setItemSpec(bo.getPackageSpec());
        priceBo.setUnits(bo.getPackageUnits());
        priceBo.setNetworkPrice(bo.getRetailPrice());
        priceBo.setPrice(bo.getRetailPrice());
        priceBo.setPreferPrice(bo.getRetailPrice());
        priceBo.setTradePrice(bo.getTradePrice());
    }

    /**
     * 修改药品价表
     */
    @Override
    public Boolean updateByBo (DrugPriceBo bo) {
        DrugPrice update = BeanUtil.toBean(bo, DrugPrice.class);
        validEntityBeforeSave(update);
        // 保存drug_price_log 药品价表日志
        bo.setOperationType(PriceConstants.OPERATION_TYPE_EDIT);
        drugPriceLogService.initDrugPriceListLog(bo);
        return baseMapper.updateById(update) > 0;
    }

    @Transactional
    public Boolean updatePriceList (DrugInfoBo bo) {
        List<DrugPriceBo> priceBoList = bo.getDrugPriceList();
        List<DrugPriceVo> list = baseMapper.selectVoList(Wrappers.<DrugPrice>lambdaQuery()
                .eq(DrugPrice::getDrugInfoId, bo.getId())
        );
        // 获取页面传的list与数据库中的差集
        List<DrugPriceVo> deletelist = list.stream()
                .filter(item -> !priceBoList.stream()
                        .map(e -> e.getId())
                        .collect(Collectors.toList())
                        .contains(item.getId()))
                .collect(Collectors.toList());
        // 有需要删除的数据
        if (CollectionUtil.isNotEmpty(deletelist)) {
            //删除
            String priceId = deletelist.get(0).getPriceId();
            // 删除drugPrice
            baseMapper.deleteById(deletelist.get(0).getId());
            // 删除price_List
            Collection<String> collection = new ArrayList<>();
            collection.add(priceId);
            // 保存drug_price_log 药品价表日志
            DrugPriceBo drugPriceBo = BeanUtil.toBean(deletelist.get(0), DrugPriceBo.class);
            drugPriceBo.setOperationType(PriceConstants.OPERATION_TYPE_DELETE);
            drugPriceLogService.initDrugPriceListLog(drugPriceBo);
            priceListService.deleteWithValidByIds(collection, true);
        }
        priceBoList.forEach(item -> {
            DrugPrice drugPrice = new DrugPrice();
            BeanUtil.copyProperties(item, drugPrice);
            baseMapper.updateById(drugPrice);
            PriceListBo priceBo = new PriceListBo();
            this.initPriceList(priceBo, item);
            priceBo.setPriceId(item.getPriceId());
            priceBo.setIntoItemCheck(true);
            // 保存drug_price_log 药品价表日志
            item.setOperationType(PriceConstants.OPERATION_TYPE_EDIT);
            drugPriceLogService.initDrugPriceListLog(item);
            priceListService.updateByBo(priceBo);
        });
        return true;
    }

    /**
     * @return
     * @Author zhangpeng
     * @Description //停止或恢复供应
     * @ date 22:25 2023/6/10
     * @Param * @param null
     **/
    @Override
    public boolean supplySignStopOrRestore (DrugPriceBo bo) {
        DrugPrice drugPrice = new DrugPrice();
        drugPrice.setId(bo.getId());
        drugPrice.setSupplySign(bo.getSupplySign());
//        drugPrice.updateInfo();
        DrugStock drugStock = new DrugStock();
        drugStock.setIsSupply(bo.getSupplySign());
        if (StringUtils.equals(bo.getSupplySign(), BaseConstants.STOP_SUPPLY)) {
            drugStock.setStopDate(new Date());
            drugStock.setStopOperator(LoginHelper.getUserId());
            bo.setOperationType(PriceConstants.OPERATION_TYPE_STOP_SUPPLY);
        } else {
            drugStock.setStopDate(null);
            drugStock.setStopOperator("");
            bo.setOperationType(PriceConstants.OPERATION_TYPE_RESTORE_ENABLE);
        }
//        drugStock.updateInfo();
        // 修改库存表对应的数据
        drugStockMapper.update(drugStock, Wrappers.<DrugStock>lambdaUpdate()
                .eq(DrugStock::getDrugPriceId, bo.getId()));
        // 保存drug_price_log 药品价表日志
        drugPriceLogService.initDrugPriceListLog(bo);
        return baseMapper.updateById(drugPrice) > 0 ? true : false;
    }

    /**
     * @return
     * @Author zhangpeng
     * @Description //药品价表停用或启用
     * @ date 22:26 2023/6/14
     * @Param * @param null
     **/
    @Override
    @GlobalTransactional
    public boolean stopPrice (DrugPriceBo bo) {
        DrugPrice drugPrice = new DrugPrice();
        drugPrice.setId(bo.getId());
        if (ObjectUtil.isNotNull(bo.getStopDate())) {
            // 停价
            drugPrice.setStopDate(DateUtils.getNowDate());
            PriceListBo priceListBo = new PriceListBo();
            priceListBo.setPriceId(bo.getPriceId());
            drugPrice.setStopDate(drugPrice.getStopDate());
            // 同时修改price_list中停止时间
            priceListService.stopPrice(priceListBo);
            bo.setOperationType(PriceConstants.OPERATION_TYPE_STOPPRICE);
        } else {
            // 启用
            drugPrice.setStopDate(null);
            // 同时修改price_list中停止时间
            PriceListBo priceListBo = new PriceListBo();
            priceListBo.setPriceId(bo.getPriceId());
            drugPrice.setStartDate(DateUtils.getNowDate());
            priceListService.priceEnable(priceListBo);
            bo.setOperationType(PriceConstants.OPERATION_TYPE_ENABLE);
        }
        // 保存drug_price_log 药品价表日志
        drugPriceLogService.initDrugPriceListLog(bo);
        return baseMapper.updateById(drugPrice) > 0 ? true : false;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave (DrugPrice entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除药品价表
     */
    @Override
    public Boolean deleteWithValidByIds (Collection<String> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * @Author zhangpeng
     * @Description // 药品 新增、修改、启用、通知工业停止供应
     * @ date 16:55 2023/6/16
     * @Param * @param null
     * @return
     **/
//    public Boolean initDrugPriceListLog(DrugPriceBo bo) {
//        DrugPrice d = BeanUtil.toBean(bo, PriceListLogBo.class);
//
//        LoginUser loginUser = LoginHelper.getLoginUser();
//        priceListLogBo.setCreateBy(loginUser.getNickName());
//        priceListLogBo.setCreateTime(DateUtils.getNowDate());
//    }
}
